use serde::{Deserialize, Serialize};

#[derive(Clone, Debug, Serialize)]
pub struct RetainReq {
    begin_date: String,
    end_date: String,
}

impl RetainReq {
    pub fn new<T>(begin: T, end: T) -> RetainReq
    where
        T: AsRef<str>,
    {
        Self {
            begin_date: begin.as_ref().to_owned(),
            end_date: end.as_ref().to_owned(),
        }
    }
}

#[derive(Clone, Debug, Deserialize)]
pub struct RetainRes {
    pub ref_date: String,
    pub visit_uv_new: Vec<VisitUv>,
    pub visit_uv: Vec<VisitUv>,
}

#[derive(Clone, Debug, Deserialize)]
pub struct VisitUv {
    pub key: u32,
    pub value: u32,
}

#[derive(Clone, Debug, Deserialize)]
pub struct VisitTrendRes {
    pub list: Vec<VisitTrend>,
}

#[derive(Clone, Debug, Deserialize)]
pub struct VisitTrend {
    pub ref_date: String,
    pub session_cnt: u32,
    pub visit_pv: u32,
    pub visit_uv: u32,
    pub visit_uv_new: u32,
    pub stay_time_session: u32,
    pub visit_depth: f32,
}

#[derive(Clone, Debug, Deserialize)]
pub struct SummaryTrend {
    pub list: Vec<SummaryTrendItem>,
}

#[derive(Clone, Debug, Deserialize)]
pub struct SummaryTrendItem {
    pub ref_date: String,
    pub visit_total: u32,
    pub share_pv: u32,
    pub share_uv: u32,
}

#[derive(Clone, Debug, Deserialize)]
pub struct VisitPage {
    pub ref_date: String,
    pub list: Vec<VisitPageItem>,
}

#[derive(Clone, Debug, Deserialize)]
pub struct VisitPageItem {
    pub page_path: String,
    pub page_visit_pv: u32,
    pub page_visit_uv: u32,
    pub page_staytime_pv: u32,
    pub entrypage_pv: u32,
    pub exitpage_pv: u32,
    pub page_share_pv: u32,
    pub page_share_uv: u32,
}

#[derive(Clone, Debug, Deserialize)]
pub struct UserPortraitRes {
    pub ref_date: String,
    pub visit_uv_new: UserPortrait,
    pub visit_uv: UserPortrait,
}

#[derive(Clone, Debug, Deserialize)]
pub struct UserPortrait {
    pub provice: UserPortraitItem,
}

#[derive(Clone, Debug, Deserialize)]
pub struct UserPortraitItem {
    pub id: u32,
    pub name: String,
    pub value: u32,
}
#[derive(Clone, Debug, Deserialize)]
pub struct VisitDistribution {
    pub ref_date: String,
    pub list: Vec<VisitDistributionItem>,
}
#[derive(Clone, Debug, Deserialize)]
pub struct VisitDistributionItem {
    // TODO: (完善index)[https://developers.weixin.qq.com/miniprogram/dev/OpenApiDoc/data-analysis/others/getVisitDistribution.html#index-%E7%9A%84%E5%90%88%E6%B3%95%E5%80%BC]
    pub index: String,
    pub item_list: Vec<DistributionValue>,
}
#[derive(Clone, Debug, Deserialize)]
pub struct DistributionValue {
    pub key: u32,
    pub value: u32,
}

#[derive(Clone, Debug, Serialize)]
pub struct PerformanceDataReq {
    module: u32,
    time: PerformanceTime,
    params: Vec<PerformanceParam>,
}

impl PerformanceDataReq {
    pub fn new(module: u32, time: &PerformanceTime, params: &[PerformanceParam]) -> Self {
        Self {
            module,
            time: time.to_owned(),
            params: params.to_owned(),
        }
    }
}

#[derive(Clone, Debug, Serialize)]
pub struct PerformanceTime {
    begin_timestamp: u32,
    end_timestamp: u32,
}

impl PerformanceTime {
    pub fn new(begin: u32, end: u32) -> Self {
        Self {
            begin_timestamp: begin,
            end_timestamp: end,
        }
    }
}

#[derive(Clone, Debug, Serialize)]
pub struct PerformanceParam {
    field: String,
    value: String,
}

impl PerformanceParam {
    pub fn new<T>(field: T, value: T) -> Self
    where
        T: AsRef<str>,
    {
        Self {
            field: field.as_ref().to_owned(),
            value: value.as_ref().to_owned(),
        }
    }
}
#[derive(Clone, Debug, Deserialize)]
pub struct PerformanceDataRes {
    pub data: PerformanceData,
}

#[derive(Clone, Debug, Deserialize)]
pub struct PerformanceData {
    pub body: PerformanceDataBody,
}

#[derive(Clone, Debug, Deserialize)]
pub struct PerformanceDataBody {
    pub tables: Vec<PerformanceDataTable>,
    pub count: u32,
}

#[derive(Clone, Debug, Deserialize)]
pub struct PerformanceDataTable {
    pub id: String,
    pub zh: String,
    pub lines: Vec<PerformanceLine>,
}

#[derive(Clone, Debug, Deserialize)]
pub struct PerformanceLine {
    pub fields: Vec<PerformanceField>,
}

#[derive(Clone, Debug, Deserialize)]
pub struct PerformanceField {
    pub refdate: String,
    pub value: String,
}
